/*
 * @(#)InfoController.java 2020-07-08
 *
 * Copyright (c) 2010 by rayootech.com. All rights reserved.
 */
package com.nuctech.formlogin.web;

import com.nuctech.formlogin.model.User;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author lilu
 * @date 2020-07-08
 * @since 1.0.0
 */
@RestController
public class InfoController {
	/**
	 * 用户信息的获取，其实办法很多，上面提到的 SecurityContextHolder.getContext().getAuthentication() 是一个静态
	 * 方法，也就是利用这个方法，我们可以随时随地拿到用户信息（需要注意 ThreadLocal 的限制）。
	 * @return
	 */
	@GetMapping("/info1")
	public User info1() {
		User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		return user;
	}

	/**
	 * 在 Controller 中的方法上，直接就可以注入 Authentication 对象，进而获取到当前用户信息
	 * @return
	 */
	@GetMapping("/info2")
	public User info2(Authentication authentication) {
		return (User)authentication.getPrincipal();
	}

	/**
	 * 更新当前登录用户信息
	 *
	 * 在 Spring Security 中，当用户登录成功之后，如果前端提供了修改用户信息的功能，在前端
	 * 修改完用户信息之后，存储在 Spring Security 中的用户信息也要及时修改，以防止在后面其
	 * 他的请求中获取到错误的用户信息，Spring Security 中用户信息要如何修改呢？
	 *
	 * @return
	 */
	@GetMapping("/updateUser")
	public User updateUser(String username, Authentication authentication) {
		// 不涉及密码和权限的更新
		User user = ((User)authentication.getPrincipal()).setUsername(username);
		SecurityContextHolder.getContext().setAuthentication(
			new UsernamePasswordAuthenticationToken(user,
				authentication.getCredentials(),
				authentication.getAuthorities()));
		return user;
	}
}
